package com.lalilu.lread

import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.os.Environment
import com.lalilu.lread.base.AbstractMMKV
import com.lalilu.lread.entity.LBook
import com.lalilu.lread.utils.compressBytesToFormat
import com.lalilu.lread.utils.saveToPath
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import nl.siegmann.epublib.domain.Book
import java.util.*

class EpubMMKV private constructor(context: Context) : AbstractMMKV<String, LBook>("epub") {
    private val pictureDictionary = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)

    @Throws(NullPointerException::class)
    suspend fun saveBookByEpubLib(uri: Uri, epubBook: Book, md5: String): LBook =
        withContext(Dispatchers.IO) {
            val identifier = "${epubBook.metadata.identifiers.firstOrNull()?.value}"

            val title = epubBook.metadata.titles.firstOrNull()
            val author = epubBook.metadata.authors.firstOrNull()
            val contributor = epubBook.metadata.contributors.firstOrNull()
            val coverUriString = epubBook.coverImage.data
                .compressBytesToFormat(60, Bitmap.CompressFormat.WEBP_LOSSY)
                .saveToPath("$pictureDictionary/cover_${epubBook.title}.webp").toString()

            val book = getByKey(md5) ?: LBook(md5)
            book.title = title
            book.identifier = identifier
            book.authors = "${author?.firstname} ${author?.lastname}"
            book.contributors = "${contributor?.firstname} ${contributor?.lastname}"
            book.language = epubBook.metadata.language
            book.pageCount = epubBook.contents.size
            book.coverUriString = coverUriString
            book.uriString = uri.toString()
            return@withContext save(book)
        }

    companion object {

        @Volatile
        private var instance: EpubMMKV? = null

        @Throws(NullPointerException::class)
        fun getInstance(context: Context?): EpubMMKV {
            instance ?: synchronized(EpubMMKV::class.java) {
                instance = instance ?: EpubMMKV(context!!)
            }
            if (instance == null) throw NullPointerException() else return instance!!
        }
    }

    override fun get(item: LBook): LBook? = getByKey(item.id)
    override fun getAll(): List<LBook>? = getAllItem()
    override fun getByKey(key: String): LBook? = mmkv.decodeParcelable(key, LBook::class.java)
    override fun saveByKey(key: String): LBook = save(LBook(key))

    override fun deleteByKey(key: String) {
        mmkv.remove(key)
    }

    override fun delete(item: LBook) {
        deleteByKey(item.id)
    }

    override fun save(item: LBook): LBook {
        mmkv.encode(item.id, item)
        return item
    }
}